<?php

/**
 * ProjectFactory
 */
class ProjectFactory extends CApplicationComponent
{
	public $sdkRoot;
	public $appRoot;
	private static $_objs = array();

	public function init()
	{
		parent::init();
		if ($this->sdkRoot === null) {
			$this->sdkRoot = Yii::getPathOfAlias('application.vendors.xunsearch-sdk'); // bundled sdk
			if ($this->appRoot === null) {
				$this->appRoot = Yii::getPathOfAlias('application.data.app');
			}
		} elseif ($this->appRoot === null) {
			$this->appRoot = $this->sdkRoot . DIRECTORY_SEPARATOR . 'php' . DIRECTORY_SEPARATOR . 'app';
		}
		$file = $this->sdkRoot . DIRECTORY_SEPARATOR . 'php' . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'XS.php';
		if (!file_exists($file)) {
			throw new CException('Invalid $sdkRoot of xunsearch-sdk');
		}
		require_once $file;
	}

	/**
	 * 获当前所有项目信息
	 * 字段信息包含: name, count, server, created
	 * @return array
	 */
	public function getAll($refresh = false)
	{
		$key = 'project.lists';
		if (!$refresh && ($ret = Yii::app()->cache->get($key)) !== false) {
			return $ret;
		}
		// re-scan
		$ret = array();
		$dir = $this->appRoot;
		if (($d = dir($dir)) === false) {
			return $ret;
		}
		while (($e = $d->read()) !== false) {
			if (($pos = strrpos($e, '.ini')) !== false) {
				$item = array(
					'name' => substr($e, 0, $pos),
					'count' => 0,
					'created' => filemtime($dir . DIRECTORY_SEPARATOR . $e),
				);
				try {
					$xs = $this->get($item['name']);
					$item['charset'] = $xs->getDefaultCharset();
					$item['server'] = $xs->search->getConnString();
					$item['count'] = $xs->search->getDbTotal();
				} catch (Exception $e) {
					if ($e->getCode() != CMD_ERR_NODB) {
						$item['error'] = $e->getMessage();
						$item['count'] = '-';
					}
				}
				$ret[] = $item;
			}
		}
		$d->close();
		Yii::app()->cache->set($key, $ret, 1800, new CFileCacheDependency($dir));
		return $ret;
	}

	/**
	 * @param string $name 项目名称
	 * @return XS 返回 XS 对象e
	 * @throws CHttpException
	 */
	public function get($name)
	{
		try {
			if (isset(self::$_objs[$name])) {
				return self::$_objs[$name];
			}
			$xs = new XS($this->appRoot . DIRECTORY_SEPARATOR . $name . '.ini');
			self::$_objs[$name] = $xs;
			return $xs;
		} catch (XSException $e) {
			$this->getAll(true);
			throw new CHttpException(500, $e->getMessage());
		}
	}

	/**
	 * 保存项目配置文件(更新/创建)
	 */
	public function save($name, $content, $create = false)
	{
		$file = $this->appRoot . DIRECTORY_SEPARATOR . $name . '.ini';
		if ($create && file_exists($file)) {
			throw new CException('该项目名已经存在，请修改项目名称');
		}
		if (@file_put_contents($file, $content) === false) {
			throw new CException('无法保存项目配置文件，请检查权限');
		}
		// force to refresh cache
		$this->getAll(true);
	}
}
